package com.sixbro.session.config;

import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.SessionRepository;
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

/**
 * <p>
 *  redis session 共享
 * </p>
 *
 * @author: Mr.Lu
 * @since: 2021-12-17 15:51
 */
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 120)
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig {

    /**
     * RedisTemplate配置
     *
     *  可以使用一下连接工厂(任意一个)：
     *  1. RedisConnectionFactory
     *  2. JedisConnectionFactory
     *  3. LettuceConnectionFactory
     *
     *
     *  例子:
     *  public RedisTemplate<Object,Object> redisTemplate(JedisConnectionFactory factory) {
     *    //配置redisTemplate
     *    RedisTemplate<Object,Object> template = new RedisTemplate<Object,Object>();
     *    template.setConnectionFactory(factory);
     *
     *    GenericFastJsonRedisSerializer serializer = new GenericFastJsonRedisSerializer();
     *    template.setDefaultSerializer(serializer);
     *    template.afterPropertiesSet();
     *    return template;
     *  }
     *
     * @param connectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<Object,Object> redisTemplate(LettuceConnectionFactory connectionFactory) {
        //配置redisTemplate
        RedisTemplate<Object,Object> template = new RedisTemplate<Object,Object>();
        template.setConnectionFactory(connectionFactory);

        template.setDefaultSerializer(RedisSerializer.json());

        //设置序列化
        RedisSerializer keySerializer = RedisSerializer.string();
        Jackson2JsonRedisSerializer valueSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        valueSerializer.setObjectMapper(objectMapper);


        // 设置value的序列化规则和 key的序列化规则
        // key序列化
        template.setKeySerializer(keySerializer);
        // Hash key序列化
        template.setHashKeySerializer(keySerializer);
        // value序列化
        template.setValueSerializer(valueSerializer);
        // Hash value序列化
        template.setHashValueSerializer(valueSerializer);
        template.afterPropertiesSet();

        return template;
    }

    /**
     * 设置spring session redis 序列化方式
     * @return
     */
    @Bean
    public SessionRepository sessionRepository() {
        return sessionRepository();
    }

    /**
     * 设置spring session redis 序列化方式
     * @param connectionFactory
     * @return
     */
    @Bean
    public SessionRepository sessionRepository(LettuceConnectionFactory connectionFactory){
        RedisOperationsSessionRepository sessionRepository =  new RedisOperationsSessionRepository(redisTemplate(connectionFactory));
        sessionRepository.setDefaultSerializer(new FastJsonRedisSerializer<Object>(Object.class));
        sessionRepository.setDefaultMaxInactiveInterval(36000);
        return sessionRepository;
    }
}
